package org.zcode.generator.core.generator.clazz;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.zcode.generator.core.config.BeanTypeConfig;
import org.zcode.generator.core.config.ImportConfig;
import org.zcode.generator.core.config.XmlConfig;
import org.zcode.generator.core.generator.ClazzCreator;
import org.zcode.generator.core.generator.method.DataSourceMethodCreator;
import org.zcode.generator.core.util.GeneratorUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description:
 * @author zhoulk
 * @date: 2019/10/30
 */
public class DatasourceServiceCreator extends ClazzCreator {

    private String tableName;
    private String tableRemarks;
    private Interface serviceInterface;
    private TopLevelClass serviceImpl;

    public DatasourceServiceCreator(XmlConfig xmlConfig, BeanTypeConfig beanTypeConfig, IntrospectedTable introspectedTable) {
        super(xmlConfig, beanTypeConfig, introspectedTable);
        this.tableRemarks = GeneratorUtil.getTableRemarks(introspectedTable.getRemarks());
        String table = introspectedTable.getBaseRecordType();
        this.tableName = table.substring(table.lastIndexOf(".") + 1).substring(xmlConfig.substring);
        methodCreator = new DataSourceMethodCreator(xmlConfig, beanTypeConfig, introspectedTable);
        init();
    }

    @Override
    protected void init() {
        serviceInterface = new Interface(beanTypeConfig.interfaceType);
        FullyQualifiedJavaType serviceType = new FullyQualifiedJavaType(xmlConfig.serviceImplPack + "." + tableName + "ServiceImpl");
        serviceImpl = new TopLevelClass(serviceType);
        serviceInterface.addJavaDocLine(GeneratorUtil.getDocTmpl(tableRemarks + "原子服务", xmlConfig.author));
        serviceImpl.addJavaDocLine(GeneratorUtil.getDocTmpl(tableRemarks + "原子服务实现", xmlConfig.author));
        addImport();
    }

    /**
     * 添加接口
     */
    @Override
    public GeneratedJavaFile createInterface() {
        List<GeneratedJavaFile> files = new ArrayList<>();
        serviceInterface.setVisibility(JavaVisibility.PUBLIC);
        // 添加方法
        Method method = methodCreator.countMethod(tableName, 1);
        method.removeAllBodyLines();
        serviceInterface.addMethod(method);

        method = methodCreator.qrysMethod(tableName, 1);
        method.removeAllBodyLines();
        serviceInterface.addMethod(method);

        if (introspectedTable.getPrimaryKeyColumns() != null && introspectedTable.getPrimaryKeyColumns().size() > 0) {
            method = methodCreator.qryByIdMethod(tableName, 1);
            method.removeAllBodyLines();
            serviceInterface.addMethod(method);
        }
        method = methodCreator.addMethod(tableName, 1);
        method.removeAllBodyLines();
        serviceInterface.addMethod(method);

        method = methodCreator.updMethod(tableName, 1);
        method.removeAllBodyLines();
        serviceInterface.addMethod(method);
        return new GeneratedJavaFile(serviceInterface, xmlConfig.datasourceTarget);
    }

    /**
     * 添加实现类
     */
    @Override
    public GeneratedJavaFile createClazz() {
        serviceImpl.setVisibility(JavaVisibility.PUBLIC);
        // 设置实现的接口
        serviceImpl.addSuperInterface(beanTypeConfig.interfaceType);
        serviceImpl.addAnnotation("@Service");
        serviceImpl.addImportedType(ImportConfig.service);
        // 添加引用dao
        addField(serviceImpl);
        // 添加方法
        Method method = methodCreator.countMethod(tableName, 0);
        method.addAnnotation("@Override");
        serviceImpl.addMethod(method);

        method = methodCreator.qrysMethod(tableName, 0);
        method.addAnnotation("@Override");
        serviceImpl.addMethod(method);
        if (introspectedTable.getPrimaryKeyColumns() != null && introspectedTable.getPrimaryKeyColumns().size() > 0) {
            method = methodCreator.qryByIdMethod(tableName, 0);
            method.addAnnotation("@Override");
            serviceImpl.addMethod(method);
        }
        method = methodCreator.addMethod(tableName, 0);
        method.addAnnotation("@Override");
        serviceImpl.addMethod(method);

        method = methodCreator.updMethod(tableName, 0);
        method.addAnnotation("@Override");
        serviceImpl.addMethod(method);
        return new GeneratedJavaFile(serviceImpl, xmlConfig.datasourceTarget);
    }

    @Override
    protected void addField(TopLevelClass serviceImpl) {
        // 添加 dao
        Field field = new Field();
        field.setName(GeneratorUtil.toLowerCase(beanTypeConfig.daoType.getShortName())); // 设置变量名
        serviceImpl.addImportedType(beanTypeConfig.daoType);
        field.setType(beanTypeConfig.daoType); // 类型
        field.setVisibility(JavaVisibility.PRIVATE);
        serviceImpl.addField(field);
    }

    @Override
    protected void addImport() {
        serviceInterface.addImportedType(beanTypeConfig.pojoType);
        serviceInterface.addImportedType(beanTypeConfig.pojoConditionType);
        serviceInterface.addImportedType(ImportConfig.listType);
        serviceImpl.addImportedType(beanTypeConfig.daoType);
        serviceImpl.addImportedType(beanTypeConfig.interfaceType);
        serviceImpl.addImportedType(beanTypeConfig.pojoType);
        serviceImpl.addImportedType(beanTypeConfig.pojoConditionType);
        serviceImpl.addImportedType(ImportConfig.listType);
        serviceImpl.addImportedType(ImportConfig.service);
        serviceImpl.addImportedType(ImportConfig.autowired);
        serviceImpl.addImportedType(ImportConfig.comConsts);
    }
}
